<template>
  <view class="verify-box" v-if="showBox">
    <view class="verify-mask" @click="close"></view>
    <view class="verify-content">
      <view class="verify-header">
        <text>{{ title }}</text>
        <view class="verify-close" @click="close">×</view>
      </view>
      <view class="verify-body">
        <!-- 调试工具按钮 - 已隐藏 -->
        <view class="debug-tools" v-if="false">
          <button class="verify-btn debug-btn" @click="debugCaptcha">调试验证码API</button>
          <view class="debug-info" v-if="debugInfo">{{debugInfo}}</view>
        </view>
        
        <!-- 滑块验证 -->
        <view v-if="componentType === 'VerifySlide'">
          <view class="verify-img-out" :style="{height: (parseInt(imgSize.height) + vSpace) + 'px'}">
            <view class="verify-img-panel" :style="{width: imgSize.width, height: imgSize.height}">
              <image :src="backImgBase ? ('data:image/png;base64,' + backImgBase) : ''" alt=""
                style="width:100%;height:100%;display:block"></image>
              <view class="verify-refresh" @click="refresh" v-show="showRefresh">
                <text class="refresh-icon">↻</text>
              </view>
              <transition name="tips">
                <text class="verify-tips" v-if="tipWords" :class="passFalg ? 'suc-bg':'err-bg'">{{ tipWords }}</text>
              </transition>
            </view>
          </view>
          <!-- 公共部分 -->
          <view class="verify-bar-area" :style="{width: imgSize.width, height: '40px', 'line-height':'40px'}">
            <text class="verify-msg" v-text="text || '向右滑动完成验证'"></text>
            <view class="verify-left-bar"
              :style="{width: leftBarWidth || '40px', height: '40px', 'border-color': leftBarBorderColor, transaction: transitionWidth}">
              <text class="verify-msg" v-text="finishText"></text>
              <view class="verify-move-block" @touchstart="start" @touchend="end" @touchmove="move"
                :style="{width:'40px', height: '40px', 'background-color': moveBlockBackgroundColor || '#fff', left: moveBlockLeft || '0', transition: transitionLeft}">
                <text class="verify-icon" :style="{color: iconColor || '#ddd'}">{{ iconText }}</text>
                <view class="verify-sub-block" :style="{'width': Math.floor(parseInt(imgSize.width)*47/310)+ 'px',
                              'height': imgSize.height,
                              'top':'-' + (parseInt(imgSize.height) + vSpace) + 'px',
                              }">
                  <image :src="blockBackImgBase ? ('data:image/png;base64,' + blockBackImgBase) : ''" alt=""
                    style="width:100%;height:100%;display:block"></image>
                </view>
              </view>
            </view>
          </view>
        </view>
        <!-- 点击文字验证 -->
        <view v-else-if="componentType === 'VerifyClick'">
          <view class="verify-tip-text">{{wordText}}{{wordTextTarget}}</view>
          <view class="verify-img-out" :style="{height: (parseInt(imgSize.height)) + 'px'}">
            <view class="verify-img-panel" :style="{width: imgSize.width, height: imgSize.height}" @click="clickWord">
              <image :src="backImgBase ? ('data:image/png;base64,' + backImgBase) : ''" alt=""
                style="width:100%;height:100%;display:block"></image>
              <view class="verify-refresh" @click.stop="refresh" v-show="showRefresh">
                <text class="refresh-icon">↻</text>
              </view>
              
              <!-- 用户点击的标记点 -->
              <view v-for="(point, index) in clickPoints" :key="index" 
                    class="click-point" 
                    :style="{left: point.x + 'px', top: point.y + 'px'}">
                {{index + 1}}
              </view>
              
              <transition name="tips">
                <text class="verify-tips" v-if="tipWords" :class="passFalg ? 'suc-bg':'err-bg'">{{ tipWords }}</text>
              </transition>
            </view>
          </view>
          <!-- 点击验证的按钮 -->
          <view class="verify-btn-row">
            <button class="verify-btn verify-btn-dark" @click.stop="resetPoints">刷新验证</button>
            <button class="verify-btn" @click.stop="submitPoints">确认提交</button>
          </view>
        </view>
        <!-- 简单验证码（备用） -->
        <view v-else>
          <image :src="captchaImg" mode="widthFix" class="verify-img" :style="imgSize" @click="refreshCaptcha"></image>
          <view class="verify-tip">点击图片刷新验证码</view>
        </view>
      </view>
      <!-- 删除这个无用的验证按钮 -->
      <view class="verify-footer" v-if="false">
        <button class="verify-btn" @click="verifyCaptcha">确定</button>
      </view>
    </view>
  </view>
</template>

<script>
import { getAjcaptcha, ajcaptchaCheck } from '@/api/api.js';
import { aesEncrypt } from './utils/ase.js';
import { resetSize } from './utils/util.js';

export default {
  name: 'Verify',
  props: {
    captchaType: {
      type: String,
      default: 'clickWord'
    },
    imgSize: {
      type: Object,
      default: () => {
        return {
          width: '330px',
          height: '155px'
        }
      }
    },
    barSize: {
      type: Object,
      default() {
        return {
          width: '310px',
          height: '40px'
        }
      }
    },
    blockSize: {
      type: Object,
      default() {
        return {
          width: '50px',
          height: '50px'
        }
      }
    },
    vSpace: {
      type: Number,
      default: 5
    }
  },
  data() {
    return {
      showBox: false,
      title: '请完成安全验证',
      captchaImg: '', // 备用验证码图片URL（简单验证码）
      componentType: 'VerifyClick', // 修改为点击文字验证模式
      // 滑块验证所需数据
      secretKey: '', // 后端返回的加密秘钥
      passFalg: false, // 验证通过标志
      backImgBase: '', // 验证码背景图片
      blockBackImgBase: '', // 验证滑块的背景图片
      backToken: "", // 后端返回的token
      startMoveTime: "", // 移动开始时间
      endMovetime: '', // 移动结束时间
      tipWords: '',
      text: '',
      finishText: '',
      setSize: {
        imgHeight: 0,
        imgWidth: 0,
        barHeight: 0,
        barWidth: 0
      },
      moveBlockLeft: '',
      leftBarWidth: '',
      moveBlockBackgroundColor: '',
      leftBarBorderColor: '#ddd',
      iconColor: '',
      iconText: '→', // 替换iconClass使用文本
      status: false, // 鼠标状态
      isEnd: false, // 是否验证完成
      showRefresh: true,
      transitionLeft: '',
      transitionWidth: '',
      debugInfo: '', // 调试信息
      // 点击文字验证所需数据
      clickPoints: [], // 用户点击的坐标点
      wordText: '请依次点击下图中的: ', // 需要点击的文字提示
      wordTextTarget: '', // 需要点击的文字
    }
  },
  methods: {
    // 显示验证框
    show() {
      this.showBox = true;
      this.refresh();
    },
    // 关闭验证框
    close() {
      this.showBox = false;
    },
    // 添加hide方法作为close的别名，兼容已有代码
    hide() {
      this.close();
    },
    // 点击文字验证相关方法
    clickWord(e) {
      if (this.clickPoints.length >= 4) {
        return; // 最多点4个点
      }
      
      try {
        // 使用uni-app的方式获取元素位置
        const query = uni.createSelectorQuery().in(this);
        query.select('.verify-img-panel').boundingClientRect(data => {
          if (!data) {
            console.error('无法获取图片面板位置');
            return;
          }
          
          // 获取点击位置
          let pageX, pageY;
          if (e.touches && e.touches[0]) {
            // 移动端触摸事件
            pageX = e.touches[0].pageX;
            pageY = e.touches[0].pageY;
          } else {
            // PC端鼠标事件
            pageX = e.pageX || e.clientX;
            pageY = e.pageY || e.clientY;
          }
          
          // 计算相对位置
          const x = pageX - data.left;
          const y = pageY - data.top;
          
          // 确保坐标在图片范围内
          if (x >= 0 && x <= data.width && y >= 0 && y <= data.height) {
            // 添加点击点
            this.clickPoints.push({ x, y });
          }
        }).exec();
      } catch (error) {
        console.error('获取点击坐标时出错:', error);
        uni.showToast({
          title: '点击操作失败，请重试',
          icon: 'none'
        });
      }
    },
    
    // 重新选择 - 完全刷新验证内容
    resetPoints() {
      console.log('重新刷新验证码');
      // 清除点击点
      this.clickPoints = [];
      
      // 显示加载提示
      uni.showLoading({
        title: '刷新中...',
        mask: true
      });
      
      // 调用刷新方法，加载新的验证内容
      this.refresh();
      
      // 隐藏加载提示
      setTimeout(() => {
        uni.hideLoading();
        uni.showToast({
          title: '已重新加载',
          icon: 'none',
          duration: 1000
        });
      }, 500);
    },
    
    // 提交点击的坐标点
    submitPoints() {
      if (this.clickPoints.length < 1) {
        uni.showToast({
          title: '请至少点击一个字',
          icon: 'none'
        });
        return;
      }
      
      // 准备验证数据
      const pointsData = this.clickPoints.map(point => {
        return {
          x: Math.round(point.x),
          y: Math.round(point.y)
        };
      });
      
      // 坐标数据转为JSON字符串
      const pointJson = this.secretKey 
        ? aesEncrypt(JSON.stringify(pointsData), this.secretKey)
        : JSON.stringify(pointsData);
      
      // 准备验证数据
      const data = {
        captchaType: this.captchaType || 'clickWord', // 确保使用点击文字验证类型
        pointJson: pointJson,
        token: this.backToken
      };
      
      // 生成验证码凭证
      const captchaVerification = this.secretKey 
        ? aesEncrypt(this.backToken + '---' + JSON.stringify(pointsData), this.secretKey)
        : this.backToken + '---' + JSON.stringify(pointsData);
      
      // 发送验证请求
      ajcaptchaCheck(data).then((result) => {
        let res = result.data;
        this.passFalg = true;
        this.tipWords = "验证成功";
        
        setTimeout(() => {
          this.close();
          this.refresh();
        }, 1500);
        
        setTimeout(() => {
          this.tipWords = "";
          this.$emit('success', {
            captchaVerification
          });
        }, 1000);
      }).catch(err => {
        this.passFalg = false;
        this.tipWords = '验证失败';
        this.resetPoints();
        
        setTimeout(() => {
          this.refresh();
        }, 1000);
      });
    },
    // 调试验证码API
    debugCaptcha() {
      this.debugInfo = '正在测试验证码API...';
      
      // 测试API响应
      getAjcaptcha({
        captchaType: this.captchaType
      }).then(res => {
        this.debugInfo = '响应成功，正在分析...';
        
        // 输出完整响应到控制台
        console.log('验证码完整响应:', res);
        
        let foundImg = false;
        let imgKeys = [];
        
        // 遍历响应寻找可能的图片数据
        const searchForImg = (obj, path = '') => {
          if (typeof obj !== 'object' || obj === null) return;
          
          for (let key in obj) {
            const newPath = path ? `${path}.${key}` : key;
            
            if (typeof obj[key] === 'string' && obj[key].length > 100) {
              // 可能是base64图片
              imgKeys.push({
                path: newPath,
                preview: obj[key].substring(0, 30) + '...'
              });
              foundImg = true;
            } else if (typeof obj[key] === 'object' && obj[key] !== null) {
              searchForImg(obj[key], newPath);
            }
          }
        };
        
        searchForImg(res);
        
        if (foundImg) {
          this.debugInfo = `找到潜在图片数据的字段:\n${JSON.stringify(imgKeys, null, 2)}`;
          
          // 尝试使用第一个找到的图片
          if (imgKeys.length > 0 && imgKeys[0].path) {
            const parts = imgKeys[0].path.split('.');
            let value = res;
            for (let part of parts) {
              value = value[part];
            }
            
            if (value && typeof value === 'string') {
              this.backImgBase = value;
              this.debugInfo += '\n\n已设置第一个图片为背景图片';
              
              // 如果有第二个，设为滑块图片
              if (imgKeys.length > 1) {
                const parts2 = imgKeys[1].path.split('.');
                let value2 = res;
                for (let part of parts2) {
                  value2 = value2[part];
                }
                
                if (value2 && typeof value2 === 'string') {
                  this.blockBackImgBase = value2;
                  this.debugInfo += '，第二个图片为滑块图片';
                }
              }
            }
          }
        } else {
          this.debugInfo = '未找到潜在的图片数据。响应结构:\n' + JSON.stringify(res, null, 2).substring(0, 300) + '...';
        }
      }).catch(err => {
        this.debugInfo = '测试失败: ' + (err.message || JSON.stringify(err));
        console.error('验证码API测试失败:', err);
      });
    },
    // 刷新验证码
    refresh() {
      // 初始化
      this.tipWords = "";
      this.moveBlockLeft = undefined;
      this.leftBarWidth = undefined;
      this.text = "向右滑动完成验证";
      this.moveBlockBackgroundColor = "#fff";
      this.leftBarBorderColor = "#ddd";
      this.iconColor = "#ddd";
      this.iconText = '→'; // 重置为箭头图标
      this.status = false;
      this.isEnd = false;
      this.clickPoints = []; // 清除点击点
      
      // 显示加载中
      this.backImgBase = '';
      this.blockBackImgBase = '';
      
      // 调用API获取验证码
      getAjcaptcha({
        captchaType: this.captchaType || 'clickWord' // 指定验证码类型为点击文字
      }).then(res => {
        // 调试输出，查看API返回的数据结构
        console.log('验证码API响应:', JSON.stringify(res));
        
        // 尝试适配不同的返回结构
        if (res.data) {
          if (res.data.repCode === '0000' || !res.data.repCode) {
            // 处理标准格式
            this.backImgBase = res.data.originalImageBase64;
            this.backToken = res.data.token;
            this.secretKey = res.data.secretKey;
            
            // 处理点击文字提示
            if (res.data.wordList && res.data.wordList.length > 0) {
              this.wordTextTarget = res.data.wordList.join(',');
            } else if (res.data.words) {
              this.wordTextTarget = res.data.words;
            }
            
            // 如果是滑块验证，还需要设置滑块图片
            if (this.componentType === 'VerifySlide' && res.data.jigsawImageBase64) {
              this.blockBackImgBase = res.data.jigsawImageBase64;
            }
          } else {
            // 如果没有识别到结构，尝试直接遍历寻找图片数据
            for (let key in res.data) {
              if (typeof res.data[key] === 'string' && res.data[key].length > 100) {
                if (!this.backImgBase) {
                  this.backImgBase = res.data[key];
                } else if (!this.blockBackImgBase && this.componentType === 'VerifySlide') {
                  this.blockBackImgBase = res.data[key];
                }
              }
              if (key === 'token') this.backToken = res.data[key];
              if (key === 'secretKey') this.secretKey = res.data[key];
              if (key === 'words' || key === 'wordList') {
                this.wordTextTarget = Array.isArray(res.data[key]) 
                  ? res.data[key].join(',') 
                  : res.data[key];
              }
            }
          }
          
          // 检查是否成功获取了图片数据
          if (!this.backImgBase) {
            uni.showToast({
              title: '验证码数据解析失败',
              icon: 'none'
            });
            console.error('未能解析验证码图片数据:', res.data);
          }
        } else {
          uni.showToast({
            title: '获取验证码失败，返回数据格式错误',
            icon: 'none'
          });
          console.error('验证码API返回格式错误:', res);
        }
      }).catch(err => {
        console.error('获取验证码失败:', err);
        uni.showToast({
          title: '获取验证码失败: ' + (err.message || JSON.stringify(err)),
          icon: 'none',
          duration: 3000
        });
      });
    },
    // 刷新简单验证码（备用）
    refreshCaptcha() {
      getAjcaptcha({
        captchaType: this.captchaType
      }).then(res => {
        if (res.data && res.data.repCode === '0000') {
          this.backToken = res.data.token;
          this.secretKey = res.data.secretKey;
          this.captchaImg = 'data:image/png;base64,' + res.data.originalImageBase64;
        } else {
          this.captchaImg = 'https://via.placeholder.com/330x155?text=加载失败，点击重试';
          uni.showToast({
            title: '验证码加载失败',
            icon: 'none'
          });
        }
      }).catch(err => {
        console.error('获取验证码失败:', err);
        this.captchaImg = 'https://via.placeholder.com/330x155?text=加载失败，点击重试';
        uni.showToast({
          title: '验证码加载失败',
          icon: 'none'
        });
      });
    },
    // 简单验证码验证（备用）
    verifyCaptcha() {
      if (!this.backToken) {
        uni.showToast({
          title: '请先获取验证码',
          icon: 'none'
        });
        this.refreshCaptcha();
        return;
      }
      
      // 发送验证请求
      ajcaptchaCheck({
        captchaType: this.captchaType,
        token: this.backToken,
        pointJson: "{}" // 简单验证不需要坐标
      }).then(res => {
        if (res.data && res.data.repCode === '0000') {
          this.$emit('success', {
            captchaVerification: this.backToken
          });
          this.close();
        } else {
          uni.showToast({
            title: '验证失败，请重试',
            icon: 'none'
          });
          this.refreshCaptcha();
        }
      }).catch(err => {
        console.error('验证失败:', err);
        uni.showToast({
          title: '验证失败，请重试',
          icon: 'none'
        });
        this.refreshCaptcha();
      });
    },
    
    // 滑块验证相关方法
    // 鼠标按下
    start: function(e) {
      this.startMoveTime = new Date().getTime(); // 开始滑动的时间
      if (this.isEnd == false) {
        this.text = ''
        this.moveBlockBackgroundColor = '#337ab7'
        this.leftBarBorderColor = '#337AB7'
        this.iconColor = '#fff'
        e.stopPropagation();
        this.status = true;
      }
    },
    // 鼠标移动
    move: function(e) {
      var query = uni.createSelectorQuery().in(this);
      this.barArea = query.select('.verify-bar-area')
      var bar_area_left, barArea_offsetWidth;
      this.barArea.boundingClientRect(data => {
        bar_area_left = Math.ceil(data.left)
        barArea_offsetWidth = Math.ceil(data.width)

        if (this.status && this.isEnd == false) {
          if (!e.touches) { // 兼容移动端
            var x = Math.ceil(e.clientX);
          } else { // 兼容PC端
            var x = Math.ceil(e.touches[0].pageX);
          }

          var move_block_left = x - bar_area_left // 小方块相对于父元素的left值
          if (move_block_left >= barArea_offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2) {
            move_block_left = barArea_offsetWidth - parseInt(parseInt(this.blockSize.width) / 2) - 2;
          }

          if (move_block_left <= 0) {
            move_block_left = parseInt(parseInt(this.blockSize.width) / 2);
          }

          // 拖动后小方块的left值
          this.moveBlockLeft = (move_block_left - parseInt(parseInt(this.blockSize.width) / 2)) + "px"
          this.leftBarWidth = (move_block_left - parseInt(parseInt(this.blockSize.width) / 2)) + "px"
        }
      }).exec();
    },
    // 鼠标松开
    end: function() {
      this.endMovetime = new Date().getTime();
      var _this = this;
      // 判断是否重合
      if (this.status && this.isEnd == false) {
        var moveLeftDistance = parseInt((this.moveBlockLeft || '').replace('px', ''));
        
        moveLeftDistance = moveLeftDistance * 310 / parseInt(this.imgSize.width)
        
        var captchaVerification = this.secretKey ? aesEncrypt(this.backToken + '---' + JSON.stringify({
          x: moveLeftDistance,
          y: 5.0
        }), this.secretKey) : this.backToken + '---' + JSON.stringify({
          x: moveLeftDistance,
          y: 5.0
        })
        
        const data = {
          captchaType: this.captchaType,
          pointJson: this.secretKey ? aesEncrypt(JSON.stringify({ 
            x: moveLeftDistance, 
            y: 5.0 
          }), this.secretKey) : JSON.stringify({ 
            x: moveLeftDistance, 
            y: 5.0 
          }),
          token: this.backToken
        };
        
        ajcaptchaCheck(data).then((result) => {
          let res = result.data
          this.moveBlockBackgroundColor = '#5cb85c'
          this.leftBarBorderColor = '#5cb85c'
          this.iconColor = '#fff'
          this.iconText = '✓'
          this.showRefresh = true
          this.isEnd = true;
          
          setTimeout(() => {
            this.close();
            this.refresh();
          }, 1500)
          
          this.passFalg = true
          this.tipWords = `${((this.endMovetime-this.startMoveTime)/1000).toFixed(2)}s验证成功`
          
          setTimeout(() => {
            this.tipWords = ""
            this.$emit('success', {
              captchaVerification
            })
          }, 1000)
        }).catch(err => {
          this.moveBlockBackgroundColor = '#d9534f'
          this.leftBarBorderColor = '#d9534f'
          this.iconColor = '#fff'
          this.iconText = '✗'
          this.tipWords = '验证失败'
          
          setTimeout(() => {
            this.refresh();
          }, 1000)
        });
      }
    }
  }
}
</script>

<style lang="scss">
.verify-box {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 9999;
  
  .verify-mask {
    position: absolute;
    top: 0;
    left: 0;
    width: 100%;
    height: 100%;
    background-color: rgba(0, 0, 0, 0.5);
  }
  
  .verify-content {
    position: absolute;
    top: 50%;
    left: 50%;
    transform: translate(-50%, -50%);
    width: 80%;
    background-color: #ffffff;
    border-radius: 16rpx;
    overflow: hidden;
    box-shadow: 0 8rpx 24rpx rgba(0, 0, 0, 0.15);
    border: 1px solid rgba(226, 129, 129, 0.1);
    
    .verify-header {
      display: flex;
      justify-content: space-between;
      align-items: center;
      padding: 20rpx 30rpx;
      border-bottom: 1px solid rgba(0, 0, 0, 0.05);
      color: #333333;
      font-size: 30rpx;
      
      .verify-close {
        font-size: 40rpx;
        color: #999999;
        width: 60rpx;
        height: 60rpx;
        display: flex;
        justify-content: center;
        align-items: center;
        border-radius: 50%;
        transition: all 0.3s;
        
        &:active {
          background-color: rgba(0, 0, 0, 0.05);
        }
      }
    }
    
    .verify-body {
      padding: 30rpx;
      text-align: center;
      
      // 点击文字验证样式
      .verify-tip-text {
        font-size: 28rpx;
        color: #333;
        margin-bottom: 20rpx;
        font-weight: bold;
      }
      
      .click-point {
        position: absolute;
        width: 24px;
        height: 24px;
        border-radius: 50%;
        background-color: rgba(226, 129, 129, 0.85);
        color: #fff;
        font-size: 14px;
        font-weight: bold;
        display: flex;
        align-items: center;
        justify-content: center;
        transform: translate(-50%, -50%);
        pointer-events: none;
        box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2);
        border: 1px solid rgba(255, 255, 255, 0.8);
        z-index: 10;
      }
      
      .verify-btn-row {
        display: flex;
        justify-content: space-between;
        margin-top: 20rpx;
        gap: 20rpx; /* 添加按钮之间的间距 */
      }
      
      .verify-btn {
        flex: 1; /* 使按钮宽度相等 */
        height: 80rpx;
        line-height: 80rpx;
        border-radius: 40rpx;
        font-size: 28rpx;
        font-weight: 500;
        letter-spacing: 1rpx;
        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.1);
        border: none;
        transition: all 0.3s;
      }
      
      .verify-btn-dark {
        background-color: #f5f5f5;
        color: #333;
        &:active {
          background-color: #e8e8e8;
        }
      }

      /* 确认提交按钮样式优化 */
      .verify-btn:not(.verify-btn-dark) {
        background-color: #e28181;
        color: #ffffff;
        box-shadow: 0 4rpx 12rpx rgba(226, 129, 129, 0.3);
        
        &:active {
          transform: translateY(2rpx);
          box-shadow: 0 2rpx 8rpx rgba(226, 129, 129, 0.3);
        }
      }
      
      // 调试工具样式
      .debug-tools {
        margin-bottom: 20rpx;
        
        .debug-btn {
          background-color: #2d8cf0;
          margin-bottom: 10rpx;
          height: 60rpx;
          line-height: 60rpx;
          font-size: 24rpx;
          width: auto;
          padding: 0 20rpx;
        }
        
        .debug-info {
          text-align: left;
          font-size: 24rpx;
          color: #666;
          background-color: #f5f5f5;
          padding: 10rpx;
          border-radius: 8rpx;
          margin-bottom: 15rpx;
          max-height: 200rpx;
          overflow-y: auto;
          white-space: pre-wrap;
        }
      }
      
      .verify-img {
        width: 100%;
        border: 1px solid rgba(226, 129, 129, 0.1);
        border-radius: 8rpx;
        box-shadow: 0 4rpx 12rpx rgba(0, 0, 0, 0.08);
      }
      
      .verify-tip {
        margin-top: 20rpx;
        color: #999999;
        font-size: 24rpx;
      }
      
      // 滑块验证样式
      .verify-img-out {
        position: relative;
        
        .verify-img-panel {
          position: relative;
          
          .verify-refresh {
            position: absolute;
            right: 5px;
            top: 5px;
            width: 30px;
            height: 30px;
            cursor: pointer;
            background: #fff;
            border-radius: 50%;
            display: flex;
            align-items: center;
            justify-content: center;
            
            .refresh-icon {
              font-size: 20px;
              color: #333;
              font-weight: bold;
            }
          }
          
          .verify-tips {
            position: absolute;
            left: 0;
            bottom: 0;
            width: 100%;
            height: 30px;
            line-height: 30px;
            color: #fff;
            text-align: center;
            
            &.suc-bg {
              background-color: rgba(92, 184, 92, 0.5);
            }
            
            &.err-bg {
              background-color: rgba(217, 83, 79, 0.5);
            }
          }
        }
      }
      
      .verify-bar-area {
        position: relative;
        background: #f5f5f5;
        text-align: center;
        box-sizing: content-box;
        border: 1px solid #ddd;
        
        .verify-msg {
          font-size: 14px;
          color: #999;
        }
        
        .verify-left-bar {
          position: absolute;
          top: -1px;
          left: -1px;
          background: #f5f5f5;
          height: 40px;
          border: 1px solid #ddd;
          box-sizing: content-box;
          
          .verify-move-block {
            position: absolute;
            top: 0;
            left: 0;
            width: 40px;
            height: 40px;
            background: #fff;
            box-sizing: border-box;
            box-shadow: 0 0 3px #ccc;
            cursor: pointer;
            transition: background .2s linear;
            display: flex;
            align-items: center;
            justify-content: center;
            
            .verify-icon {
              font-size: 20px;
            }
            
            .verify-sub-block {
              position: absolute;
              overflow: hidden;
              box-sizing: border-box;
            }
          }
        }
      }
    }
    
    .verify-footer {
      padding: 20rpx 30rpx 40rpx;
      text-align: center;
    }
  }
}

// 动画
.tips-enter-active {
  transition: all .5s;
}
.tips-enter {
  transform: translateX(100%);
}
.tips-enter-to {
  transform: translateX(0);
}
</style> 